package statistics;

import java.math.BigDecimal;

import datastructures.UserParameters;
import edu.rit.numeric.Statistics;

public class Phi_Contrasts extends AbstractStatisticTests implements IStatisticalTest 
{	
	
	static BigDecimal[] lnFactorialList = new BigDecimal[5000];
	static {
		lnFactorialList[0] = new BigDecimal("0");
		for(int i=1; i<5000; i++) {
			BigDecimal number = new BigDecimal( Math.log( i ) );
			lnFactorialList[i] = lnFactorialList[i-1].add(number);
		}
	}
	
	public Phi_Contrasts (UserParameters userParams) {
		super(userParams);
	}
	
	/*
	 * (non-Javadoc)
	 * @see statistics.AbstractStatisticTests#TestCasesOnly(int, int[][][], int[][][], int)
	 */
	public double TestCasesOnly ( int order, int[][] observedCases ) 
	{		
		double z_cases = TestCasesOnly_Zscore(order, observedCases);
		double probability = Statistics.chiSquarePvalue(1, Math.pow(z_cases,2)) ; // / 2;
		return probability;
	}
	
	/*
	 * (non-Javadoc)
	 * @see statistics.AbstractStatisticTests#TestCasesVsControls(int, int[][][], int[][][], int, int[][][], int[][][], int)
	 */
	public double TestCasesVsControls ( int order, int[][] observedCases, int[][] observedControls ) 
	{ 
		double z_diff = TestCasesVsControls_Zscore(order, observedCases, observedControls);
		double probability = Statistics.chiSquarePvalue(1, Math.pow(z_diff,2)) ; // / 2;
		return probability;
	};
	
	
	public double TestCasesOnly_Zscore ( int order, int[][] observedCases ) 
	{	
//		int totalCases = observedCases[1][1] + observedCases[1][0] + observedCases[0][1] + observedCases[0][0] ;
		double phi_coeff = ( observedCases[1][1] * observedCases[0][0] ) - ( observedCases[1][0] * observedCases[0][1] ) ;
		double std_dev = Math.sqrt ( 
															(double) (observedCases[1][1]+observedCases[1][0]) 
															* (observedCases[1][1]+observedCases[0][1])
															* (observedCases[0][0]+observedCases[0][1])	
															* (observedCases[0][0]+observedCases[1][0]) 
															/ totalCases
													  ) ;		
		double z_cases = phi_coeff / std_dev ;
		return z_cases;
	}
	
	
	public double TestCasesVsControls_Zscore ( int order, int[][] observedCases, int[][] observedControls ) 
	{ 
//		int totalCases = observedCases[1][1] + observedCases[1][0] + observedCases[0][1] + observedCases[0][0] ;
		double phi_coeff_cases = ( observedCases[1][1] * observedCases[0][0] ) - ( observedCases[1][0] * observedCases[0][1] ) ;		
		double var_cases = (double) (observedCases[1][1]+observedCases[1][0]) 
										* (observedCases[1][1]+observedCases[0][1])
										* (observedCases[0][0]+observedCases[0][1])	
										* (observedCases[0][0]+observedCases[1][0]) 
										/ totalCases ;
		
//		int totalControls = observedControls[1][1] + observedControls[1][0] + observedControls[0][1] + observedControls[0][0] ;
		double phi_coeff_controls = ( observedControls[1][1] * observedControls[0][0] ) - ( observedControls[1][0] * observedControls[0][1] ) ;
		double var_controls = (double) (observedControls[1][1]+observedControls[1][0]) 
										* (observedControls[1][1]+observedControls[0][1])
										* (observedControls[0][0]+observedControls[0][1])	
										* (observedControls[0][0]+observedControls[1][0]) 
										/ totalControls ;
		
		double z_contrast = ( phi_coeff_cases - phi_coeff_controls ) / Math.sqrt ( var_cases + var_controls ) ;
		return z_contrast;
	}
	
}
